;; Benchmarks of the matrix chain multiplication functions
;; Copyright (C) 2022  Rocks Mazama
;; 
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; 
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;; 
;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

(ns bench
  (:require
   [criterium.core :as criterium]
   [mazama.linalg.matrix-chain :refer [matrix-chain]]))

(defn- fncols [A]
  (:ncols A))

(defn- fnrows [A]
  (/ (count (:data A)) (:ncols A)))

(defn- make-matrix [nrows ncols]
  {:ncols ncols :data (repeatedly (* nrows ncols) #(- (rand-int 100) 50))})

(defn- make-matrix-sequence [dims]
  (map make-matrix dims (rest dims)))

(defn- make-dims [n]
  (repeatedly n #(inc (rand-int 50))))

(defn- run [dims]
  (println \newline (dec (count dims)) "matrices...")
  (let [coll (doall (make-matrix-sequence dims))]
    (criterium/quick-bench (matrix-chain fnrows fncols coll))))

(defn -main []
  (let [dims [[3 8 1 2 5 7 6 1 8 4 7 5 2 1 9]
              (make-dims 141)]]
    (doseq [dim dims] (run dim))))
